﻿/**
 * Copyright (C) 2011 original author and authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using NGuice.Inject.Internal.Util;
using System.Reflection;
using NGuice.Inject.Internal;
using System.Collections;

namespace NGuice.Inject.Spi
{
    //complete!
    /// <summary>
    /// 一个能够接受注入的构造器、域、属性、方法的注入点。一般是使用元特性标记[Inject]的成员。
    /// 对于非私有无参的构造器，成员将忽略元特性
    /// </summary>
    public sealed class InjectionPoint
    {
        private static readonly EventLog logger = Logger.GetLog(typeof(InjectionPoint));

        private readonly bool optional;

        private readonly MemberInfo member;

        private readonly Type declaringType;

        private readonly IList<Dependency> dependencies;

        internal InjectionPoint(Type declaringType, MethodInfo method, bool optional)
        {
            this.member = method;
            this.declaringType = declaringType;
            this.optional = optional;
            this.dependencies = ForMember(method, declaringType, method.GetParameterAttributes());
        }

        internal InjectionPoint(Type declaringType, ConstructorInfo constructor)
        {
            this.member = constructor;
            this.declaringType = declaringType;
            this.optional = false;
            this.dependencies = ForMember(constructor, declaringType, constructor.GetParameterAttributes());
        }

        internal InjectionPoint(Type declaringType, FieldInfo field, bool optional)
        {
            this.member = field;
            this.declaringType = declaringType;
            this.optional = optional;
            Attribute[] annotations = (Attribute[])field.GetCustomAttributes(true);
            Errors errors = new Errors(field);
            Key key = null;
            try
            {
                key = Attributes.GetKey(field.FieldType, field, annotations, errors);
            }
            catch (ConfigurationException e)
            {
                errors.Merge(e.ErrorMessages);
            }
            catch (ErrorsException e)
            {
                errors.Merge(e.Errors);
            }
            errors.ThrowConfigurationExceptionIfErrorsExist();
            this.dependencies = new ReadOnlyList<Dependency>(Lists.NewArrayList(NewDependency(key, Attributes.AllowsNull(annotations), -1)));
        }

        internal InjectionPoint(Type declaringType, PropertyInfo property, bool optional)
        {
            this.member = property;
            this.declaringType = declaringType;
            this.optional = optional;
            Attribute[] annotations = (Attribute[])property.GetCustomAttributes(true);
            Errors errors = new Errors(property);
            Key key = null;
            try
            {
                key = Attributes.GetKey(property.PropertyType, property, annotations, errors);
            }
            catch (ConfigurationException e)
            {
                errors.Merge(e.ErrorMessages);
            }
            catch (ErrorsException e)
            {
                errors.Merge(e.Errors);
            }
            errors.ThrowConfigurationExceptionIfErrorsExist();
            this.dependencies = new ReadOnlyList<Dependency>(Lists.NewArrayList(NewDependency(key, Attributes.AllowsNull(annotations), -1)));
        }

        private IList<Dependency> ForMember(MemberInfo member, Type type, Attribute[][] paramterAnnotations)
        {
            Errors errors = new Errors(member);
            IEnumerator<Attribute[]> annotationsEnumerator = paramterAnnotations.AsEnumerable().GetEnumerator();
            List<Dependency> dependencies = Lists.NewArrayList<Dependency>();
            int index = 0;

            foreach (Type parameterType in GetGenericParameterTypes(member, type))
            {
                try
                {
                    annotationsEnumerator.MoveNext();
                    Attribute[] parameterAnnotations = annotationsEnumerator.Current;
                    Key key = Attributes.GetKey(parameterType, member, parameterAnnotations, errors);
                    dependencies.Add(NewDependency(key, Attributes.AllowsNull(parameterAnnotations), index));
                    index++;
                }
                catch (ConfigurationException e)
                {
                    errors.Merge(e.ErrorMessages);
                }
                catch (ErrorsException e)
                {
                    errors.Merge(e.Errors);
                }
            }
            errors.ThrowConfigurationExceptionIfErrorsExist();
            return new ReadOnlyList<Dependency>(dependencies);
        }

        /// <summary>
        /// 根据成员类型（方法或构造）解析泛型参数类型
        /// </summary>
        /// <param name="member"></param>
        /// <returns></returns>
        public Type[] GetGenericParameterTypes(MemberInfo methodOrConstructor, Type subType)
        {
            Type[] genericParameterTypes;

            if (methodOrConstructor is MethodInfo)
            {
                MethodInfo method = (MethodInfo)methodOrConstructor;
                Preconditions.CheckArgument(method.DeclaringType.IsAssignableFrom(subType),
                    string.Format("{0} is not defined by a supertype of {1}", method, subType));
                genericParameterTypes = method.GetGenericArguments();

            }
            else if (methodOrConstructor is ConstructorInfo)
            {
                ConstructorInfo constructor = (ConstructorInfo)methodOrConstructor;
                Preconditions.CheckArgument(constructor.DeclaringType.IsAssignableFrom(subType),
                  string.Format("{0} does not construct a supertype of {1}", constructor, subType));
                //C#中构造器不支持泛型参数，所有从其声明的类型中获取泛型参数
                genericParameterTypes = /*constructor.GetGenericArguments()*/constructor.DeclaringType.GetGenericArguments();

            }
            else
            {
                throw new ArgumentException("Not a method or a constructor: " + methodOrConstructor);
            }
            return genericParameterTypes;
        }

        //// This metohd is necessary to create a Dependency<T> with proper generic type information
        //private Dependency<T> NewDependency<T>(Key<T> key, bool allowsNull, int parameterIndex)
        //{
        //    return new Dependency<T>(this, key, allowsNull, parameterIndex);
        //}

        /// <summary>
        /// 注入点对象基本都通过反射获取依赖类型，因此泛型方法基本无用，只能使用返回标记接口
        /// 的方式获取依赖，但此依赖对象的泛型参数具有和key相同的泛型参数类型！
        /// </summary>
        /// <param name="key">具有泛型参数的Key</param>
        /// <param name="allowsNull"></param>
        /// <param name="parameterIndex"></param>
        /// <returns>与Key的泛型参数相同的泛型参数类型的依赖对象</returns>
        private Dependency NewDependency(Key key, bool allowsNull, int parameterIndex)
        {
            if (!key.GetType().IsGenericType)
            {
                throw new ArgumentException("the key must be a generic type");
            }
            Type genericType = key.GetType().GetGenericArguments()[0];
            return (Dependency)typeof(Dependency<>).GetConstructor(new Type[] { typeof(InjectionPoint), key.GetType(), typeof(bool), typeof(int) }).Invoke(new object[] { this, key, allowsNull, parameterIndex });
        }

        /// <summary>
        /// 获取注入的构造器、域或方法
        /// </summary>
        public MemberInfo Member
        {
            // TODO: Don't expose the original member (which probably has setAccessible(true)).
            get
            {
                return member;
            }
        }

        /// <summary>
        /// 获取此注入点的依赖列表。如果注入点是一个方法或构造器，则依赖将对应方法的参数。域注入点总是
        /// 单独对应域本身的。注意：由于C#的泛型是一个确定的类型，他不能使用？作为通配符，因此返回的列
        /// 表不适用泛型列表，内部的元素也是dynamic动态解析的，但其始终是某个Denpendency<?>类型
        /// </summary>
        public IList<Dependency> Dependencies
        {
            get
            {
                return dependencies;
            }
        }

        /// <summary>
        /// 如果当注入器不能够为所有请求的依赖解析绑定时，此注入点是否要忽略。显式绑定（在模块中指定）和
        /// 隐式绑定（使用ImplementedBy元特性）都支持可选。默认的构造器等都支持可选注入点
        /// </summary>
        public bool IsOptional
        {
            get
            {
                return optional;
            }
        }

        /// <summary>
        /// 注入点成员是否使用Toolable元特性标注
        /// </summary>
        public bool IsToolable
        {
            get
            {
                return Attribute.GetCustomAttribute(member, typeof(ToolableAttribute)) != null;
            }
        }


        /// <summary>
        /// 获取注入点声明的类型
        /// </summary>
        public Type DeclaringType
        {
            get
            {
                return declaringType;
            }
        }

        public override bool Equals(object o)
        {
            return o is InjectionPoint
                && member.Equals(((InjectionPoint)o).member)
                && declaringType.Equals(((InjectionPoint)o).declaringType);
        }

        public override int GetHashCode()
        {
            return member.GetHashCode() ^ declaringType.GetHashCode();
        }

        public override string ToString()
        {
            return Classes.ToString(member);
        }

        /// <summary>
        /// 为指定的构造器生成一个注入点
        /// </summary>
        public static InjectionPoint ForConstructor(ConstructorInfo constructor)
        {
            return new InjectionPoint(constructor.DeclaringType, constructor);
        }

        /// <summary>
        /// 由于C#泛型是一个确定的类型，因此这里直接判断type是否为指定构造器所声明类型的子类型
        /// </summary>
        public static InjectionPoint ForConstructor(ConstructorInfo constructor, Type type)
        {
            if (!type.IsSubclassOf(constructor.DeclaringType) || type != constructor.DeclaringType)
            {
                new Errors(type)
                    .ConstructorNotDefinedByType(constructor, type)
                    .ThrowConfigurationExceptionIfErrorsExist();
            }
            return new InjectionPoint(type, constructor);
        }

        /// <summary>
        /// 为一个确切的使用Inject元特性注释的构造器或无参非私有的构造器生成注入点
        /// </summary>
        /// <param name="type">一个确切的使用Inject元特性注释的构造器或无参非私有的构造器声明的类型</param>
        /// <exception cref="ConfigurationException">
        /// 如果类型中没有可注入的构造器，或具有多个可注入的构造器或者可注入构造器的参数是无效的（例如参数具有多个绑定注释）
        /// </exception>
        public static InjectionPoint ForConstructorOf(Type type)
        {
            Errors errors = new Errors(type);

            ConstructorInfo injectableConstructor = null;
            foreach (ConstructorInfo constructor in type.GetConstructors())
            {

                bool optional = false;
                InjectAttribute[] guiceInject = (InjectAttribute[])constructor.GetCustomAttributes(typeof(InjectAttribute), true);
                if (guiceInject.Length == 0)
                {
                    continue;
                }
                else
                {
                    optional = guiceInject[0].Optional;
                }

                if (optional)
                {
                    errors.OptionalConstructor(constructor);
                }

                if (injectableConstructor != null)
                {
                    errors.TooManyConstructors(type);
                }

                injectableConstructor = constructor;
                CheckForMisplacedBindingAnnotations(injectableConstructor, errors);
            }

            errors.ThrowConfigurationExceptionIfErrorsExist();

            if (injectableConstructor != null)
            {
                return new InjectionPoint(type, injectableConstructor);
            }
            //如果没有找到标注的构造器，则查找无参的构造器
            try
            {
                ConstructorInfo noArgConstructor = type.GetConstructor(Type.EmptyTypes);
                if (noArgConstructor.IsPrivate && type.IsVisible)
                {
                    //不允许在非私有类中定义私有构造器能注入
                    errors.MissingConstructor(type);
                    throw new ConfigurationException(errors.Messages);
                }
                CheckForMisplacedBindingAnnotations(noArgConstructor, errors);
                return new InjectionPoint(type, noArgConstructor);
            }
            catch (Exception e)
            {
                errors.MissingConstructor(type);
                throw new ConfigurationException(errors.Messages);
            }
        }



        /// <summary>
        /// 当绑定元注释在错误的地方时返回true
        /// </summary>
        private static bool CheckForMisplacedBindingAnnotations(MemberInfo member, Errors errors)
        {
            object[] atts = member.GetCustomAttributes(false);
            Attribute[] attributes = new Attribute[atts.Length];
            for (int i = 0; i < atts.Length; i++)
            {
                attributes[i] = atts[i] as Attribute;
            }
           
            Attribute misplacedBindingAnnotation = Attributes.FindBindingAnnotation(errors, member, attributes);
            if (misplacedBindingAnnotation == null)
            {
                return false;
            }
            errors.MisplacedBindingAnnotation(member, misplacedBindingAnnotation);
            return true;
        }

        /// <summary>
        /// 获取所有静态方法和域以及属性的注入点集合
        /// </summary>
        /// <returns>
        /// 可能为空集合。集合有指定的迭代顺序。首先迭代所有域，然后属性然后方法。在域和属性中，超类的域（属性）将在子类
        /// 域（属性）之前返回。同样，超类方法也在子类方法之前返回
        /// </returns>
        /// <exception ref="ConfigurationException">在类型中有无效的注入点例如一个域有多个绑定</exception>
        public static ISet<InjectionPoint> ForStaticMethodsAndFields(Type type)
        {
            Errors errors = new Errors();
            ISet<InjectionPoint> result = GetInjectionPoints(type, true, errors);
            if (errors.HasErrors)
            {
                throw new ConfigurationException(errors.Messages).WithPartialValue(result);
            }
            return result;
        }

        /// <summary>
        /// 返回所有实例域、属性和方法的注入点
        /// </summary>
        public static ISet<InjectionPoint> ForInstanceMethodsAndFields(Type type)
        {
            Errors errors = new Errors();
            ISet<InjectionPoint> result = GetInjectionPoints(type, false, errors);
            if (errors.HasErrors)
            {
                throw new ConfigurationException(errors.Messages).WithPartialValue(result);
            }
            return result;
        }

        /// <summary>
        /// 获取一个给定类型的按照顺序的不可变注入点集合。超类成员排序在子类成员之前，域排序在属性之前，属性在方法之前。覆盖的方法被过滤
        /// </summary>
        /// <param name="statics">表示此方法返回静态注入点还是动态注入点</param>
        private static ISet<InjectionPoint> GetInjectionPoints(Type type, bool statics, Errors errors)
        {
            InjectableMembers injectableMembers = new InjectableMembers();
            OverrideIndex overrideIndex = null;
            List<Type> hierarchy = HierarchyFor(type);
            int topIndex = hierarchy.Count - 1;
            for (int i = topIndex; i >= 0; i--)
            {
                if (overrideIndex != null && i < topIndex)
                {
                    // Knowing the position within the hierarchy helps us make optimizations.
                    if (i == 0)
                    {
                        overrideIndex.position = Position.BOTTOM;
                    }
                    else
                    {
                        overrideIndex.position = Position.MIDDLE;
                    }
                }

                Type current = hierarchy[i];

                foreach (FieldInfo field in current.GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    //获得类中声明的所有字段（包括公共，保护，私有，内部, 静态）但不包括继承的字段
                    if (field.IsStatic == statics)
                    {
                        //静态成员标记是否与参数一致
                        Attribute atInject = GetAtInject(field);
                        if (atInject != null)
                        {
                            InjectableField injectableField = new InjectableField(current, field, atInject);
                            //if (injectableField.jsr330 && Modifier.isFinal(field.getModifiers())) {
                            //  errors.cannotInjectFinalField(field);
                            //}
                            injectableMembers.Add(injectableField);
                        }
                    }
                }

                foreach (PropertyInfo property in current.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    //获得类中声明的所有属性（包括公共，保护，私有，内部, 静态）但不包括继承的字段
                    if (property.GetSetMethod().IsStatic == statics)
                    {
                        //静态属性标记是否与参数一致
                        Attribute atInject = GetAtInject(property);
                        if (atInject != null)
                        {
                            InjectableProperty injectableProperty = new InjectableProperty(current, property, atInject);
                            //if (injectableField.jsr330 && Modifier.isFinal(field.getModifiers())) {
                            //  errors.cannotInjectFinalField(field);
                            //}
                            injectableMembers.Add(injectableProperty);
                        }
                    }
                }

                foreach (MethodInfo method in current.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Static))
                {
                    if (method.IsStatic == statics)
                    {
                        Attribute atInject = GetAtInject(method);
                        if (atInject != null)
                        {
                            InjectableMethod injectableMethod = new InjectableMethod(current, method, atInject);
                            if (CheckForMisplacedBindingAnnotations(method, errors))
                            {
                                if (overrideIndex != null)
                                {
                                    bool removed = overrideIndex.RemoveIfOverriddenBy(method, false, injectableMethod);
                                    if (removed)
                                    {
                                        logger.WriteEntry(string.Format("Method: {0} is not a valid injectable method ("
                                            + "because it either has misplaced binding annotations "
                                            + "or specifies type parameters) but is overriding a method that is valid. "
                                            + "Because it is not valid, the method will not be injected. "
                                            + "To fix this, make the method a valid injectable method.", method), EventLogEntryType.Warning);
                                    }
                                }
                                continue;
                            }
                            if (statics)
                            {
                                injectableMembers.Add(injectableMethod);
                            }
                            else
                            {
                                if (overrideIndex == null)
                                {
                                    /*
                                     * Creating the override index lazily means that the first type in the hierarchy
                                     * with injectable methods (not necessarily the top most type) will be treated as
                                     * the TOP position and will enjoy the same optimizations (no checks for overridden
                                     * methods, etc.).
                                     */
                                    overrideIndex = new OverrideIndex(injectableMembers);
                                }
                                else
                                {
                                    //强制删除覆盖的方法，否则我们会注入两次
                                    overrideIndex.RemoveIfOverriddenBy(method, true, injectableMethod);
                                }
                                overrideIndex.Add(injectableMethod);
                            }
                        }
                        else
                        {
                            if (overrideIndex != null)
                            {
                                bool removed = overrideIndex.RemoveIfOverriddenBy(method, false, null);
                                //if(removed) {
                                //  logger.log(Level.WARNING, "Method: {0} is not annotated with @Inject but "
                                //      + "is overriding a method that is annotated with @javax.inject.Inject.  Because "
                                //      + "it is not annotated with @Inject, the method will not be injected. "
                                //      + "To fix this, annotate the method with @Inject.", method);
                                //}
                            }
                        }
                    }
                }
            }

            if (injectableMembers.IsEmpty())
            {
                return ImmutableSet<InjectionPoint>.EMPTY_IMMUTABLE_SET;
            }

            ImmutableSet<InjectionPoint>.Builder<InjectionPoint> builder = ImmutableSet<InjectionPoint>.GetBuilder();
            for (InjectableMember im = injectableMembers.head; im != null; im = im.next)
            {
                try
                {
                    builder.Add(im.ToInjectionPoint());
                }
                catch (ConfigurationException ignorable)
                {
                    if (!im.optional)
                    {
                        errors.Merge(ignorable.ErrorMessages);
                    }
                }
            }
            return builder.Build();
        }

        internal static Attribute GetAtInject(MemberInfo member)
        {
            Attribute[] attr = (Attribute[])member.GetCustomAttributes(typeof(InjectAttribute), false);
            if (attr.Length == 0)
                return null;
            return attr[attr.Length - 1];
        }

        /// <summary>
        /// 获取type继承层次链表
        /// </summary>
        private static List<Type> HierarchyFor(Type type)
        {
            List<Type> hierarchy = new List<Type>();
            Type current = type;
            while (current != typeof(object))
            {
                hierarchy.Add(current);
                current = current.BaseType;
            }
            return hierarchy;
        }
    }

    /// <summary>
    /// 可注入成员的双向链表节点（域、属性和方法）
    /// </summary>
    internal abstract class InjectableMember
    {
        internal Type declaringType;
        internal bool optional;
        //bool jsr330;
        internal InjectableMember previous;
        internal InjectableMember next;

        internal InjectableMember(Type declaringType, Attribute atInject)
        {
            this.declaringType = declaringType;
            //if (atInject.annotationType() == javax.inject.Inject.class) {
            //  optional = false;
            //  jsr330 = true;
            //  return;
            //}
            //jsr330 = false;
            optional = ((InjectAttribute)atInject).Optional;
        }

        internal abstract InjectionPoint ToInjectionPoint();
    }

    internal class InjectableField : InjectableMember
    {
        internal readonly FieldInfo field;
        internal InjectableField(Type declaringType, FieldInfo field, Attribute atInject)
            : base(declaringType, atInject)
        {
            this.field = field;
        }

        internal override InjectionPoint ToInjectionPoint()
        {
            return new InjectionPoint(declaringType, field, optional);
        }
    }

    internal class InjectableProperty : InjectableMember
    {
        internal readonly PropertyInfo property;
        internal InjectableProperty(Type declaringType, PropertyInfo property, Attribute atInject)
            : base(declaringType, atInject)
        {
            this.property = property;
        }

        internal override InjectionPoint ToInjectionPoint()
        {
            return new InjectionPoint(declaringType, property, optional);
        }
    }

    internal class InjectableMethod : InjectableMember
    {
        internal readonly MethodInfo method;

        //如果此方法覆盖了使用Inject元特性注释的方法，则为true
        internal bool overrodeGuiceInject;
        internal InjectableMethod(Type declaringType, MethodInfo method, Attribute atInject)
            : base(declaringType, atInject)
        {
            this.method = method;
        }

        internal override InjectionPoint ToInjectionPoint()
        {
            return new InjectionPoint(declaringType, method, optional);
        }

        public bool IsFinal()
        {

            return method.IsFinal;
        }
    }

    internal class InjectableMembers
    {
        internal InjectableMember head;
        internal InjectableMember tail;

        internal void Add(InjectableMember member)
        {
            if (head == null)
            {
                head = tail = member;
            }
            else
            {
                member.previous = tail;
                tail.next = member;
                tail = member;
            }
        }

        internal void Remove(InjectableMember member)
        {
            if (member.previous != null)
            {
                member.previous.next = member.next;
            }
            if (member.next != null)
            {
                member.next.previous = member.previous;
            }
            if (head == member)
            {
                head = member.next;
            }
            if (tail == member)
            {
                tail = member.previous;
            }
        }

        internal bool IsEmpty()
        {
            return head == null;
        }
    }

    /// <summary>
    /// 一个方法签名，用户处理重写的方法
    /// </summary>
    internal class Signature
    {

        readonly string name;
        readonly Type[] parameterTypes;
        readonly int hash;

        internal Signature(MethodInfo method)
        {
            this.name = method.Name;
            this.parameterTypes = method.GetParameters().Map(s =>
            {
                return s.ParameterType;
            }).ToArray();

            int h = name.GetHashCode();
            h = h * 31 + parameterTypes.Length;
            foreach (Type parameterType in parameterTypes)
            {
                h = h * 31 + parameterType.GetHashCode();
            }
            this.hash = h;
        }

        public override int GetHashCode()
        {
            return this.hash;
        }

        public override bool Equals(object o)
        {
            if (!(o is Signature))
            {
                return false;
            }
            Signature other = (Signature)o;
            if (!name.Equals(other.name))
            {
                return false;
            }
            if (parameterTypes.Length != other.parameterTypes.Length)
            {
                return false;
            }
            for (int i = 0; i < parameterTypes.Length; i++)
            {
                if (parameterTypes[i] != other.parameterTypes[i])
                {
                    return false;
                }
            }
            return true;
        }
    }

    /// <summary>
    /// 类层次中的位置
    /// </summary>
    internal enum Position
    {
        TOP, // 顶层类不需要检查覆盖方法
        MIDDLE,
        BOTTOM // 最底层不需要覆盖
    }
    /// <summary>
    /// 保持可注入方法的跟踪以便我们可以以o(1)的时间复杂度移除覆盖方法
    /// </summary>
    internal class OverrideIndex
    {
        internal readonly InjectableMembers injectableMembers;
        internal IDictionary<Signature, List<InjectableMethod>> bySignature;//存储属于同一个方法签名的覆盖方法列表
        internal Position position = Position.TOP;

        internal OverrideIndex(InjectableMembers injectableMembers)
        {
            this.injectableMembers = injectableMembers;
        }

        // 缓存最后一个方法
        MethodInfo lastMethod;
        Signature lastSignature;

        /// <summary>
        /// 删除被指定方法重写的方法。如果alwaysRemove参数为false，他将不会删除覆盖的方法，但覆盖签名将使用Inject元特性注释
        /// </summary>
        /// <param name="method">决定覆盖的要删除的方法</param>
        /// <param name="alwaysRemove">如果覆盖的方法即使他么具有Inject注释也应该被删除则为true</param>
        /// <param name="injectableMethod">可注入的方法</param>
        internal bool RemoveIfOverriddenBy(MethodInfo method, bool alwaysRemove, InjectableMethod injectableMethod)
        {
            if (position == Position.TOP)
            {
                // If we're at the top of the hierarchy, there's nothing to override.
                return false;
            }

            if (bySignature == null)
            {
                // We encountered a method in a subclass. Time to index the
                // methods in the parent class.
                bySignature = new Dictionary<Signature, List<InjectableMethod>>();
                for (InjectableMember member = injectableMembers.head; member != null; member = member.next)
                {
                    if (!(member is InjectableMethod)) continue;
                    InjectableMethod im = (InjectableMethod)member;
                    if (im.IsFinal()) continue;
                    List<InjectableMethod> methods = new List<InjectableMethod>();
                    methods.Add(im);
                    bySignature.Add(new Signature(im.method), methods);
                }
            }

            lastMethod = method;
            Signature signature = lastSignature = new Signature(method);
            List<InjectableMethod> meths = bySignature[signature];
            bool removed = false;
            if (meths != null)
            {
                InjectableMethod[] copy = meths.ToArray();
                for (int i = 0; i < copy.Length; i++)
                {
                    InjectableMethod possiblyOverridden = copy[i];
                    if (Overrides(method, possiblyOverridden.method))
                    {
                        bool wasGuiceInject = true;
                        if (injectableMethod != null)
                        {
                            injectableMethod.overrodeGuiceInject = wasGuiceInject;
                        }
                        // Only actually remove the methods if we want to force
                        // remove or if the signature never specified @com.google.inject.Inject
                        // somewhere.
                        if (alwaysRemove || !wasGuiceInject)
                        {
                            removed = true;
                            meths.Remove(possiblyOverridden);
                            injectableMembers.Remove(possiblyOverridden);
                        }
                    }
                }
            }
            return removed;
        }

        /// <summary>
        /// 如果a重写了b方法，这里已经架设a的声明类是b的声明类的子类并且a与b具有相同的签名
        /// </summary>
        internal static bool Overrides(MethodInfo a, MethodInfo b)
        {
            return b.IsVirtual;
        }

        /// <summary>
        /// 添加给定的方法到注入点列表，在这个索引下保持覆盖的跟踪
        /// </summary>
        /// <param name="injectableMethod"></param>
        internal void Add(InjectableMethod injectableMethod)
        {
            injectableMembers.Add(injectableMethod);
            if (position == Position.BOTTOM || injectableMethod.IsFinal())
            {
                // This method can't be overridden, so there's no need to index it.
                return;
            }
            if (bySignature != null)
            {
                // Try to reuse the signature we created during removal
                Signature signature = injectableMethod.method == lastMethod ? lastSignature : new Signature(injectableMethod.method);
                List<InjectableMethod> methods = bySignature[signature];
                if (methods == null)
                {
                    methods = new List<InjectableMethod>();
                    bySignature.Add(signature, methods);
                }
                methods.Add(injectableMethod);
            }
        }
    }
}
